package ch.common.dao.impl;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.junit.Test;

import ch.common.dao.BaseDao;

public class BaseDaoImpl<T> implements BaseDao<T>{
	// Spring注入
	private SessionFactory sessionFactory;
	
	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}
	// 依赖注入需要的setter方法
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}
	
	@Test
	@Override
	@SuppressWarnings("unchecked")
	public T get(Class<T> entityClazz, Serializable id) {
		// TODO Auto-generated method stub
		return (T) getSessionFactory().getCurrentSession().get(entityClazz, id);
	}

	@Override
	public Serializable save(T entity) {
		// TODO Auto-generated method stub
		return getSessionFactory().getCurrentSession().save(entity);
	}

	@Override
	public void update(T entity) {
		// TODO Auto-generated method stub
		getSessionFactory().getCurrentSession().update(entity);
	}

	@Override
	public void delete(T entity) {
		// TODO Auto-generated method stub
        getSessionFactory().getCurrentSession().delete(entity);
	}

	@Override
	public void delete(Class<T> entityClazz, Serializable id) {
		// TODO Auto-generated method stub
        getSessionFactory().getCurrentSession()
        	.createQuery("delete " + entityClazz.getSimpleName() + " en where en.id = ?0").setParameter("0", id)
        	.executeUpdate();
	}

	@Override
	public List<T> findAll(Class<T> entityClazz) {
		// TODO Auto-generated method stub
        return find("select en from " + entityClazz.getSimpleName() + " en");
	}

	@Override
	public long findCount(Class<T> entityClazz) {
		// TODO Auto-generated method stub
		List<?> l = find("select count(*) from " + entityClazz.getSimpleName());
        // 返回查询得到的实体总数
        if (l != null && l.size() == 1) {
            return (Long) l.get(0);
        }
        return 0;
	}

	@Override
	public long findCount(Class<T> entityClazz,String where) {
		// TODO Auto-generated method stub
		List<?> l = find("select count(*) from " + entityClazz.getSimpleName() + " " + where);
		// 返回查询得到的实体总数
		if (l != null && l.size() == 1) {
		    return (Long) l.get(0);
		}
		return 0;
	}
	

	// 根据HQL语句查询实体
    @SuppressWarnings("unchecked")
    protected List<T> find(String hql) {
        return (List<T>) getSessionFactory().getCurrentSession().createQuery(hql).list();
    }
    

    // 根据带占位符参数HQL语句查询实体
    @SuppressWarnings("unchecked")
	protected List<T> find(String hql, Object... params) {
        // 创建查询
        Query query = getSessionFactory().getCurrentSession().createQuery(hql);
        // 为包含占位符的HQL语句设置参数
        for (int i = 0, len = params.length; i < len; i++) {
            query.setParameter(i + "", params[i]);
        }
        return (List<T>) query.list();
    }
    
    /**
     * 使用hql 语句进行分页查询操作
     * @param hql 需要查询的hql语句
     * @param pageNo 查询第pageNo页的记录
     * @param pageSize 每页需要显示的记录数
     * @return 当前页的所有记录
     */
    @SuppressWarnings("unchecked")
    public List<T> findByPage(String hql, int pageNo, int pageSize) {
        // 创建查询
        return getSessionFactory().getCurrentSession().createQuery(hql)
                // 执行分页
                .setFirstResult((pageNo - 1) * pageSize).setMaxResults(pageSize).list();
    }

    /**
     * 使用hql 语句进行分页查询操作
     * @param hql 需要查询的hql语句
     * @param params 如果hql带占位符参数，params用于传入占位符参数
     * @param pageNo 查询第pageNo页的记录
     * @param pageSize 每页需要显示的记录数
     * @return 当前页的所有记录
     */
    @SuppressWarnings("unchecked")
	public List<T> findByPage(String hql, int pageNo, int pageSize, Object... params) {
        // 创建查询
        Query query = getSessionFactory().getCurrentSession().createQuery(hql);
        // 为包含占位符的HQL语句设置参数
        for (int i = 0, len = params.length; i < len; i++) 
        {
            query.setParameter(i + "", params[i]);
        }
        // 执行分页，并返回查询结果
        return query.setFirstResult((pageNo - 1) * pageSize).setMaxResults(pageSize).list();
    }
}
